<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2006 by CANTICO ({@link http://www.cantico.fr})
 */
//include_once 'base.php';

//require_once $GLOBALS['babInstallPath'] . 'utilit/devtools.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/widget.class.php';




/**
 * A Widget_InputWidget is the base widget of all widgets where the user can
 * input data.
 * 
 * @abstract
 */
class Widget_InputWidget extends Widget_Widget
{

	private $_mandatory;
	private $_mandatoryMessage;
	private $_value = '';
	private $_associatedLabel = null;
	
	/**
	 * @param string $id			The item unique id.
	 * @return Widget_InputWidget
	 */
	public function __construct($id = null)
	{
		parent::__construct($id);
		$this->setMandatory(false);
		$this->_dialog = null;
	}
	

	/**
	 * Checks if the field has been set as mandatory.
	 * 
	 * @return bool
	 */
	public function isMandatory()
	{
		return $this->_mandatory; 
	}
	

	/**
	 * Sets the value.
	 * The value is set in the parent form widget if possible or set into the input widget
	 *
	 * @param mixed $value
	 */
	public function setValue($value)
	{
		
		$form = $this->getForm();
		if (!$form) {
			$this->_value = $value;
			return $this;
		}
		$form->setValue($this->getNamePath(), $value);
		return $this;
	}

	/**
	 * Returns the value.
	 * The value stored in form widget is returned first if exist
	 * or the value of the field is returned
	 *
	 * @return mixed
	 */
	public function getValue()
	{
		$form = $this->getForm();
		if (!$form) {
			return $this->_value;
		}
		
		$formvalue = $form->getValue($this->getNamePath());
		
		if (null !== $formvalue) {
			
			return $formvalue;
		}
		
		return $this->_value;
	}


	/**
	 * Sets whether the field is mandatory or not.
	 * 
	 * If the field is inside a dialog, the dialog will report an error to
	 * the user if he did not fill in the field on submit.
	 * This method returns the widget itself so that other methods can be chained.
	 * 
	 * @param boolean $mandatory
	 * @param string $message		The message displayed by the dialog if the field is left empty.
	 * @return Widget_Widget
	 */
	public function setMandatory($mandatory = true, $message = '')
	{
		assert('is_bool($mandatory); /* The "mandatory" parameter must be a boolean. */');
		assert('is_string($message); /* The "message" parameter must be a string. */');
		$this->_mandatory = $mandatory;
		$this->_mandatoryMessage = $message;
		
		if ($this->_mandatory) {
			$this->setMetadata('mandatoryErrorMessage', $message);
		}
		return $this;
	}
	
	
	/**
	 * Test mandatory field
	 * @throw Widget_InputMandatoryException
	 * 
	 * @see Widget_Form::testMandatory()
	 * 
	 * @return bool
	 */
	public function testMandatory()
	{
		if ($this->_mandatory && ('' === (string) $this->getValue())) {
			throw new Widget_InputMandatoryException($this, $this->_mandatoryMessage);
			return false;
		}
		
		return true;
	}
	



	/**
	 * Returns the form to which this input widget is attached.
	 *
	 * @return Widget_Form
	 */
	public function getForm()
	{
		for ($widget = $this; $widget && (!($widget instanceof Widget_Form)); $widget = $widget->getParent()) {
			;
		}

		return $widget;
	}



	/**
	 * Returns the full name of the element as an array.
	 *
	 * @return array
	 */
	public function getFullName()
	{
		if ('' === (string) $this->getName()) {
			return array(); 
		}

		return $this->getNamePath();
	}



	
	
	/**
	 * Sets the label associated to inputwidget.
	 *
	 * @param Widget_Label $widget
	 */
	public function setAssociatedLabel(Widget_Label $widget = null)
	{
		$this->_associatedLabel = $widget;
		if ($this !== $widget->getAssociatedWidget()) {
			$widget->setAssociatedWidget($this);
		}
		return $this;
	}


	/**
	 * Returns the label associated to widget.
	 *
	 * @return Widget_Label	The widget or null if no label is associated
	 */
	public function getAssociatedLabel()
	{
		return $this->_associatedLabel;
	}


	/**
	 * @return array
	 */
	public function getClasses()
	{
		$classes = parent::getClasses();
		if ($this->_mandatory) {
			$classes[] = 'widget-input-mandatory';
		}
		
		return $classes;
	}
	
	
	
	/**
	 * Set a widget do be displayed only if the value of the input widget match the ID of the widget or one of values set in the second parameter
	 * this can be called for more than one widget
	 * 
	 * @param 	Widget_Displayable_Interface 	$displayable
	 * @param	array							$values
	 * 
	 * @return Widget_InputWidget
	 */
	public function setAssociatedDisplayable(Widget_Displayable_Interface $displayable, $values = null)
	{
		if (null === $values)
		{
			$values = array($displayable->getId());
		}
		
		$a = $this->getMetadata('displayable');
		if (null === $a)
		{
			$a = array(array($displayable->getId(), $values));
			$this->addClass('widget-associated-displayable');
		} else {
			$a[] = array($displayable->getId(), $values);
		}
		
		$this->setMetadata('displayable', $a);
		return $this;
	}
}


/**
 * Exception used to report a mandatory field error
 * @see Widget_InputWidget::testMandatory()
 * @see Widget_Form::testMandatory()
 */
class Widget_InputMandatoryException extends UnexpectedValueException
{
	private $field = null;
	
	public function __construct(Widget_InputWidget $field, $message)
	{
		parent::__construct($message);
		$this->field = $field;
	}
	
	/**
	 * Get widget witch report the error
	 * @return Widget_InputWidget
	 */
	public function getField()
	{
		return $this->field;
	}
}

